<template>
  <div v-loading.fullscreen.lock="loading"
       element-loading-text="拼命加载中"
       element-loading-spinner="el-icon-loading"
       element-loading-background="rgba(0, 0, 0, 0.8)">
    <!--三级分类-->
    <el-card style="margin: 10px">
     <!--当从基础属性列表界面 跳转 到基础属性新增界面时; 三级分类要禁用!-->
      <ClassSelector @change="selectorChange" :disabled="!showList"></ClassSelector>
    </el-card>

    <!--基础属性列表区域-->
    <el-card v-show="showList"  style="margin: 10px">
      <!--当三级分类还有没有确定时; 基础属性列表界面的添加属性按钮要禁用!-->
      <el-button type="primary" icon="el-icon-circle-plus" :disabled="!category3Id"
                 style="margin-bottom: 10px" @click="toAdd">添加属性</el-button>
      <!--表格 属性列表-->
      <el-table :data="tableData" style="width: 100%" border >
        <el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
        <el-table-column prop="attrName" label="属性名称" width="150"  align="center"></el-table-column>
        <el-table-column label="属性值列表"  align="center">
            <template slot-scope="{row}">
              <el-tag type="info" v-for="val in row.attrValueList" :key="val.id">
                {{val.valueName}}
              </el-tag>
            </template>
        </el-table-column>
        <el-table-column prop="date" label="操作" width="150"  align="center">
          <template slot-scope="{row}">
            <TipButton content="修改" placement="top" effect="light"
              size="mini" type="primary" icon="el-icon-edit" @click="toUpdate(row)"></TipButton>

            <el-popconfirm :title="`确定要删除${row.name}吗？`" @onConfirm="delAttr(row.id)">
              <TipButton content="删除" placement="top" effect="light"
                         size="mini" type="danger" icon="el-icon-delete" slot="reference">
              </TipButton>
            </el-popconfirm>

          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!--基础属性新增&修改区域-->
    <el-card v-show="!showList" style="margin: 10px">
      <el-form>
        <el-form-item label="属性名">
          <el-input placeholder="请输入属性名" style="width: 200px" v-model.trim="attrName"></el-input>
        </el-form-item>
      </el-form>
      <!--按钮-->
      <el-button type="primary" icon="el-icon-circle-plus"
                 @click="addAttrVal"  :disabled="!attrName">添加属性值</el-button>
      <el-button @click="showList=true" :disabled="saveDisabled">取消</el-button>
      <!--表格 属性值列表-->
      <el-table :data="attrValList" style="width: 100%;margin: 15px auto" border >
        <el-table-column  type="index" label="序号" width="80" align="center"></el-table-column>
        <el-table-column  label="属性值名称"  align="center">
           <template slot-scope="{row, column, $index}">
             <!--编辑-->
             <el-input v-if="row.isEdit" v-model.trim="row.name" placeholder="请输入属性值"
                       :ref="`input-${$index}`"  @blur="blurFn(row,$index)"
                       @keydown.13.native="blurFn(row,$index)"></el-input>
             <!--显示-->
             <div v-else @dblclick="showToEdit(row,$index)">{{row.name}}</div>
           </template>
        </el-table-column>
        <el-table-column  label="操作" width="350"  align="center">
          <template slot-scope="{row,$index}">
            <el-popconfirm :title="`确定要删除${row.name}吗？`" @onConfirm="delAttrVal($index)">
              <!--popconfirm的reference插槽的click事件是不能被占用的!!!-->
              <TipButton content="删除" placement="top" effect="light" :disabled="saveDisabled"
                         size="mini" type="danger" icon="el-icon-delete" slot="reference">
              </TipButton>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!--按钮-->
      <el-button type="primary" style="margin-bottom: 10px" :loading="loadingForSave"
                 @click="save" :disabled="saveDisabled">保存</el-button>
      <el-button @click="cancel" >取消</el-button>
    </el-card>
  </div>
</template>

<script>
  export default {
    name: "attr",
    data(){
      return {
        test:"xx",
        /*列表界面需要的数据*/
        tableData:[],  //属性列表
        category1Id:"",
        category2Id:"",
        category3Id:"",
        showList:true, //显示基础属性列表区域(true)  显示基础属性新增区域(false)

        /*新增界面需要的数据*/
        attrName:"" ,//新增界面的属性名
        attrValList:[],//属性值列表  [{name:"",isEdit:true}]
        dog1:false, //输入的值为空时 当前dog1为true
        dog2:false, //输入的值已经存在 当前dog2为true

        //查询请求时的loading效果
        loading:false,
        //新增修改请求时的loading效果
        loadingForSave:false
      }
    },
    computed:{
      /*当基础属性新增界面的属性名输入框为空时 或者 属性值列表为空时 或者 输入不合法时(输入为空 输入重复)
          以上不管哪个条件成立 当前保存按钮都应该禁用 saveDisabled都应该为true*/
      saveDisabled(){
        let row = this.attrValList[this.attrValList.length-1];
        let dog1 = row && row.name === "";
        let dog2 = row && this.attrValList.filter((item)=>item.name === row.name).length>=2;

        // 当基础属性新增界面的属性名输入框为空时 或者 属性值列表为空时
        let flag1 = (!this.attrName) || (this.attrValList.length===0)
        // 输入不合法时
        let flag2 = dog1 || dog2;
        return flag1 || flag2;
      }
    },
    methods:{
      //取消操作
      cancel(){
        //养一条狗 咬逻辑(输入的值不能为空)
        if(this.dog1) return;
        if(this.dog2) return;
        this. showList=true
      },



      //删除属性
      async delAttr(id){
        const {code} = await this.$api.product.attr.delAttr(id);
        if(code === 200){
          //重新刷新列表界面
          await this.getAttrInfoList()
        }
      },
      //点击保存按钮 新增 或 修改属性
      async save(){
        this.loadingForSave = true;
        let attr = {
          attrName: this.attrName,
          attrValueList:this.attrValList.map(item=>({ valueName:item.name, })),
          categoryId:this.category3Id,
          categoryLevel: 3
        };

        //修改!!!!
        if(JSON.stringify(this.row) !== "{}"){attr.id = this.row.id;}

        const {code} = await this.$api.product.attr.addOrUpdateUpdateAttr(attr);
        if(code === 200){
          //显示列表界面
          this.showList = true;
          //重新刷新列表界面
          await this.getAttrInfoList()
        };
        this.loadingForSave = false;
      },
      //跳转到编辑界面 做表单回显
      toUpdate(row){
        //如果vm实例对象上存在row属性 row属性值不为"" 说明是在进行编辑逻辑
        this.row = row;
        //数据回显
        this.attrName = row.attrName;
        this.attrValList = row.attrValueList.map(item=>({name:item.valueName}));
        //隐藏列表界面 打开新增编辑共用的界面
        this.showList=false
      },
      //跳转到新增界面 不用做表单回显
      toAdd(){
        //如果vm实例对象上存在row属性 row属性值为"" 说明是在进行新增逻辑
        this.row = {};
        //不做数据回显
        this.attrName = "";
        this.attrValList = [];
        //隐藏列表界面 打开新增编辑共用的界面
        this.showList=false
      },


      //删除属性值
      delAttrVal(index){
        // 我们不允许在 输入不合法的情况下 进行删除
        this.attrValList.splice(index,1)
      },
      //双击div切换为input
      showToEdit(row,index){
        //不管新增修改 都$set
        this.$set(row,"isEdit",true)
        //让当前input选中
        this.$nextTick(()=>{
          this.$refs[`input-${index}`].focus()
        })
      },
      //当属性值输入框失去焦点 或 用户按下回车时触发  (编辑模式切换为显示模式)
      blurFn(row,index){
        //敲回车进入当前方法时 input没有失焦
        this.$refs[`input-${index}`].blur();
        //判断输入是否为空
        if(row.name === ""){
          this.dog1 = true;
          this.$message.closeAll();
          this.$message.error("属性值不能为空");
          this.$refs[`input-${index}`].focus();
          return;
        }
        //判断输入是否重复  flag:代表输入重复了
        let flag = this.attrValList.filter((item)=>item.name === row.name).length>=2;
        if(flag){
          this.dog2 = true;
          this.$message.closeAll();
          this.$message.error("属性值不能重复");
          this.$refs[`input-${index}`].focus();
          return;
        }
        //重置!!!!
        this.dog1 = false;
        this.dog2 = false;
        //显示span
        row.isEdit = false;
      },
      //点击添加属性值按钮
      addAttrVal(){
        //养一条狗 咬逻辑(输入的值不能为空)
        if(this.dog1) return;
        if(this.dog2) return;

        //构建一个属性值对象 塞到attrValList中  name:属性值得名称 isEdit:属性值是否可编辑
        let attrVal = {name:"",isEdit:true}
        //每一次push列表多一行
        this.attrValList.push(attrVal)

        //等attrValList引起的界面更新完毕之后再去拿最新的input
        //自动让最新的input获取焦点
        this.$nextTick(()=>{
          let lastIndex = this.attrValList.length -1
          this.$refs[`input-${lastIndex}`].focus()
        })
      },


      //三级分类产生变化
      async selectorChange({class:type,classId}){
        //type:代表的是几级分类(1,2,3 代表分类级别)  classId代表的是对应分类的id
        switch (type) {
            case 1:
              this.category1Id = classId;
              //清空其他数据
              this.category2Id=""
              this.category3Id=""
              this.tableData=[]
              break;
            case 2:
              this.category2Id = classId;
              //清空其他数据
              this.category3Id=""
              this.tableData=[]
              break;
            case 3:
              this.category3Id = classId;
              //当第三级分类产生改变时 要发送请求获取基础属性信息
              await this.getAttrInfoList()
              break;
        }
      },
      //获取基础属性信息
      async getAttrInfoList(){
        this.loading = true;
        const {category1Id,category2Id,category3Id} = this;
        const {code,data} =  await this.$api.product.attr
                .getAttrInfoList({category1Id,category2Id,category3Id});
        if(code===200){
          this.tableData = data;
        }
        this.loading = false;
      }
    },
    async mounted() {
      //为了以后测试方便! 先在生命周期中发送一次获取基础属性的请求!
      // await this.getAttrInfoList()
    }
  }
</script>

<style scoped>

</style>
